package cn.xiangxu.com.webclient_rest_client.proxy;

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

/**
 * @author 王杨帅
 * @create 2018-08-24 15:26
 * @desc 基于WebClient的远程调用工具类
 **/
public class WebClientRestHandler implements RestHandler {
    @Override
    public Object restResult(ServerInfo serverInfo, MethodInfo methodInfo) {
        System.out.println("调用类：" + serverInfo);
        System.out.println("调用类：" + methodInfo);

        // 01 初始化WebClient
        WebClient webClient = WebClient.builder()
                .baseUrl(serverInfo.getBaseUrl())
                .build();

        // 02 封装Http类型、请求路径、请求参数
        WebClient.RequestBodySpec requestBodySpec = webClient
                .method(methodInfo.getHttpMethod())
                .uri(methodInfo.getHttpUrl(), methodInfo.getRequestParams())
                .accept(MediaType.APPLICATION_JSON_UTF8);

        // 03 封装请求体参数并获取响应数据
        WebClient.ResponseSpec retrieve = null;
        if (methodInfo.getBodyParam() != null) {
            retrieve = requestBodySpec
                    .body(methodInfo.getBodyParam(), methodInfo.getBodyParamEelementType())
                    .retrieve();
        } else {
            retrieve = requestBodySpec.retrieve();
        }

        retrieve.onStatus(
                httpStatus -> HttpStatus.NOT_FOUND == httpStatus,
                response -> Mono.just(new RuntimeException("请求资源不存在"))
        );

        // 04 封装响应数据
        if (methodInfo.getReturnFlux()) {
            return retrieve.bodyToFlux(methodInfo.getReturnElementType());
        } else {
            return retrieve.bodyToMono(methodInfo.getReturnElementType());
        }

    }
}

